package com.by.common.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TokenTemplate {
    TokenProperties properties;
    public TokenTemplate(TokenProperties tokenProperties){
        this.properties=tokenProperties;
    }
    //生成token
    public String generateToken(Map payload){
        String token = JWT.create()
                .withHeader(getHeader())
                .withPayload(payload)
                .withExpiresAt(getValidDate()) //给token设置有效期
                .sign(Algorithm.HMAC256(properties.getSecret()));
        return token;
    }

    //验证token
    public ValidResult validate(String token){
        if (null == token || "".equals(token))
            return  new ValidResult(0,"token为空",null);
        //不为空 验证
        DecodedJWT decodedJWT = null;
        try{
            decodedJWT = JWT.require(Algorithm.HMAC256(properties.getSecret()))
                    .build()
                    .verify(token);
        }catch (TokenExpiredException e){
            return new ValidResult(0,"token已过期",null);
        }catch (Exception e){
            return new ValidResult(1,"token无效",null);
        }
        //验证通过
        Map<String, Claim> map = decodedJWT.getClaims();
        return new ValidResult(2,"验证成功",convert(map));
    }

    //刷新token
    public String refreshToken(String token){
        //验证token
        ValidResult result = validate(token);
        if (result.getCode()==1){ //token无效
            return null;
        } else if (result.getCode()==0){
            //说明过期
            DecodedJWT decodedJWT = JWT.decode(token);
            //获取用户信息
            Map<String,Claim> map = decodedJWT.getClaims();
            //生成新的token
            return generateToken(convert(map));
        }
        //token正常时刷新
        Map map = result.getUser();
        //生成新的token
        return generateToken(map);
    }

    Map<String,String> convert(Map<String,Claim> map){
        Map<String,String> tmp = new HashMap<>();
        //遍历map
        map.forEach((key,value)->{
            tmp.put(key,value.asString());
        });
        return tmp;
    }

    //获取30s后的日期
    Date getValidDate(){
        long time = System.currentTimeMillis()+properties.getValidTime();
        Date now = new Date(time);
        return now;
    }
    //头部
    Map getHeader(){
        Map map = new HashMap();
        map.put("typ","JWT");
        map.put("alg","HS256");
        return map;
    }
}
